package com.pro.back.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pro.back.bean.*;
import com.pro.back.bean.bo.*;
import com.pro.back.bean.common.ApiRes;
import com.pro.back.bean.po.DeviceAddDto;
import com.pro.back.bean.po.DevicePO;
import com.pro.back.bean.po.RepairPO;
import com.pro.back.dao.*;
import com.pro.back.service.DeviceService;
import com.pro.back.util.CodeUtil;
import net.bytebuddy.asm.Advice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * @Author: jingwenjuan
 * @Description:
 * @Date: 2025-04-19
 */
@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private BorrowMapper borrowMapper;
    @Autowired
    private RepairMapper repairMapper;
    @Autowired
    private DeviceAddMapper deviceAddMapper;
    @Autowired
    private DeviceAddInfoMapper deviceAddInfoMapper;
    @Autowired
    private RepairInfoMapper repairInfoMapper;

    /**
     * 查询所有的设备分类信息
     *
     * @return
     */
    @Override
    public ApiRes selectDeviceType() {
        List<DeviceType> list = deviceTypeMapper.selectByExample(null);
        return new ApiRes(list);
    }

    /**
     * 新增或编辑设备类别信息
     *
     * @param type
     * @return
     */
    @Override
    public ApiRes insertDeviceType(DeviceType type) {
        if (type.getId() != null) {
            deviceTypeMapper.updateByPrimaryKeySelective(type);
        } else {
            deviceTypeMapper.insertSelective(type);
        }
        return new ApiRes("success");
    }

    @Override
    public ApiRes delDeviceType(Long id) {
        DeviceTypeExample ex = new DeviceTypeExample();
        ex.createCriteria().andIdEqualTo(id);
        deviceTypeMapper.deleteByPrimaryKey(id);
        return new ApiRes("success");
    }


    /**
     * 分页条件查询所有的设备
     *
     * @param po
     * @return
     */
    @Override
    public ApiRes selectAllDevice(DevicePO po) {
        PageHelper.startPage(po .getPageNum(), po.getPageSize());
        List<DeviceBO> list = deviceMapper.selectAll(po);
        PageInfo<DeviceBO> info = new PageInfo<>(list);
        return new ApiRes(info);
    }

    /**
     * 设备采购
     * 1. 设备编号不能重复
     *
     * @param device
     * @return
     */
    @Override
    public ApiRes insertDevice(Device device) {
        DeviceExample ex = new DeviceExample();
        ex.createCriteria().andDeviceCodeEqualTo(device.getDeviceCode());
        List<Device> list = deviceMapper.selectByExample(ex);
        if (list != null && list.size() > 0) {
            return new ApiRes(500, null, "已存在该编号的设备，请重试!");
        }

        device.setInsertDate(new Date());
        deviceMapper.insertSelective(device);
        return new ApiRes("success");
    }

    /**
     * 编辑设备信息
     * 1. 设备编号不能重复
     *
     * @param device
     * @return
     */
    @Override
    public ApiRes updateDevice(Device device) {
        deviceMapper.updateByPrimaryKeySelective(device);
        return new ApiRes("success");
    }

    /**
     * 删除设备
     * 1. 判断该设备是否在借出状态,是的话提示不能删除
     * 2. 判断该设备是否在检修中，是的话提示不能删除
     * 2. 删除设备，删除设备的借还记录，删除设备的检修记录
     */
    @Override
    @Transactional
    public ApiRes delDevice(Long id) {
        DeviceExample ex = new DeviceExample();
        ex.createCriteria().andIdEqualTo(id).andBorrowStatusEqualTo("1");
        List<Device> list = deviceMapper.selectByExample(ex);
        if (list != null && list.size() > 0) {
            return new ApiRes(500, null, "该设备已经被借出，暂时不能删除!");
        }

        DeviceExample example2 = new DeviceExample();
        example2.createCriteria().andRepairStatusEqualTo("2");
        List<Device> devices = deviceMapper.selectByExample(example2);
        if (devices != null && devices.size() > 0) {
            return new ApiRes(500, null, "该设备正在检修中，暂时不能删除！");
        }

        deviceMapper.deleteByPrimaryKey(id);

        BorrowExample example = new BorrowExample();
        example.createCriteria().andDeviceIdEqualTo(id);
        borrowMapper.deleteByExample(example);

        RepairExample example1 = new RepairExample();
        example1.createCriteria().andDeviceIdEqualTo(id);
        repairMapper.deleteByExample(example1);

        return new ApiRes("success");
    }

    /**
     * 分页条件查询设备采购申请
     *
     * @param dto
     * @return
     */
    @Override
    public ApiRes selectAllDeviceAdd(DeviceAddDto dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<DeviceAddVo> list = deviceAddMapper.selectAll(dto);
        PageInfo<DeviceAddVo> info = new PageInfo<>(list);
        return new ApiRes(info);
    }

    /**
     * 新增或编辑设备采购申请
     *
     * @param add
     * @return
     */
    @Override
    public ApiRes insertDeviceAdd(DeviceAdd add) {
        if (add.getId() != null) {
            deviceAddMapper.updateByPrimaryKeySelective(add);
        } else {
            add.setCreateTime(new Date());
            deviceAddMapper.insertSelective(add);
        }
        return new ApiRes("success");
    }

    /**
     * 删除设备采购申请记录
     *
     * @param id
     * @return
     */
    @Override
    public ApiRes delDeviceAdd(Long id) {
        deviceAddMapper.deleteByPrimaryKey(id);
        return new ApiRes("success");
    }

    /**
     * 设备入库
     * 1. 新增入库记录
     * 2. 修改设备采购状态
     * 3. 新增设备信息
     *
     * @param info
     * @return
     */
    @Override
    @Transactional
    public ApiRes insertDeviceInfo(DeviceAddInfo info) {
        info.setCreateTime(new Date());
        deviceAddInfoMapper.insertSelective(info);

        DeviceAdd add = new DeviceAdd();
        add.setId(info.getAddId());
        add.setStatus("3");
        deviceAddMapper.updateByPrimaryKeySelective(add);

        Integer num = info.getNum();
        for (int i = 0; i < num; i++) {
            Device device = new Device();
            device.setDeviceTypeId(info.getDeviceTypeId());
            device.setName(info.getName());
            device.setInsertDate(new Date());
            //生成设备编码
            device.setDeviceCode("DC"+ CodeUtil.random10Digit());
            device.setPrice(info.getPrice());
            deviceMapper.insertSelective(device);
        }

        return new ApiRes(info);
    }

    /**
     * 根据设备入库id查看设备的入库信息
     *
     * @param id
     * @return
     */
    @Override
    public ApiRes selectDeviceInfoByAdd(Long id) {
        DeviceAddInfo info = deviceAddInfoMapper.selectDeviceInfoByAdd(id);
        return new ApiRes(info);
    }

    /**
     * 新增维修记录
     * 1. 新增记录
     * 2. 结束维修
     * @param info
     * @return
     */
    @Override
    @Transactional
    public ApiRes insertRepairInfo(RepairInfo info) {
        info.setEndTime(new Date());
        repairInfoMapper.insertSelective(info);

        Repair repair = repairMapper.selectByPrimaryKey(info.getRepairId());

        Device device = new Device();
        device.setId(repair.getDeviceId());
        device.setRepairStatus("0");
        deviceMapper.updateByPrimaryKeySelective(device);

        repair.setStatus("3");
        repair.setRepairEndDate(new Date());
        repairMapper.updateByPrimaryKeySelective(repair);
        return new ApiRes(info);
    }

    /**
     * 根据维修id查看维修信息
     * @param id
     * @return
     */
    @Override
    public ApiRes selectByRepairId(Long id) {
        RepareInfoBo res = repairInfoMapper.selectByRepairId(id);
        return new ApiRes(res);
    }

    /**
     * 设备检修申请信息导出
     * @param response
     * @return
     */
    @Override
    public ApiRes exportRepair(HttpServletResponse response) throws IOException {
        RepairPO po = new RepairPO();
        po.setName("");
        List<RepairBO> list = repairMapper.selectAll(po);
        if (!CollectionUtils.isEmpty(list)) {
            for (RepairBO bo :list) {
                String status = bo.getStatus();
                switch (status) {
                    case "0" :
                        bo.setStatus("报修审核中");
                        break;
                    case "1" :
                        bo.setStatus("报修拒绝");
                        break;
                    case "2" :
                        bo.setStatus("检修中");
                        break;
                    case "3" :
                        bo.setStatus("检修完成");
                        break;
                }
            }
        }

        //模板地址
        ClassPathResource res = new ClassPathResource("files/repair.xlsx");
        InputStream inputStream = res.getInputStream();

        if (inputStream == null) {
            System.out.println("检修申请信息模板文件未获取");
            throw new RuntimeException("检修申请信息未获取,请联系管理员");
        }
        ExcelWriter excelWriter = null;
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = "检修申请信息";
            String fileNameURL = URLEncoder.encode(fileName+".xlsx", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename="+fileNameURL+";"+"filename*=utf-8''"+fileNameURL);

            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
            excelWriter.fill(list, fillConfig, writeSheet);
        } catch (Exception e) {
            throw new RuntimeException("检修申请信息下载失败");
        } finally {
            excelWriter.finish();
        }
        return new ApiRes(null);
    }

    /**
     * 查看保费状态的设备
     * @param response
     * @return
     */
    @Override
    public ApiRes exportDelDevice(HttpServletResponse response) throws IOException {
        DevicePO po = new DevicePO();
        po.setRepairStatus("3");
        List<DeviceBO> list = deviceMapper.selectAll(po);
        if (!CollectionUtils.isEmpty(list)) {
            for (DeviceBO deviceBO : list) {
                deviceBO.setStatus("报废");
            }
        }

        //模板地址
        ClassPathResource res = new ClassPathResource("files/delDevice.xlsx");
        InputStream inputStream = res.getInputStream();

        if (inputStream == null) {
            System.out.println("设备报废信息模板文件未获取");
            throw new RuntimeException("设备报废信息未获取,请联系管理员");
        }
        ExcelWriter excelWriter = null;
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = "设备报废信息";
            String fileNameURL = URLEncoder.encode(fileName+".xlsx", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename="+fileNameURL+";"+"filename*=utf-8''"+fileNameURL);

            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
            excelWriter.fill(list, fillConfig, writeSheet);
        } catch (Exception e) {
            throw new RuntimeException("设备报废信息数据下载失败");
        } finally {
            excelWriter.finish();
        }
        return new ApiRes(null);
    }



}
